<template>
  <div class="picture-comment-page" v-show="show">
    <div class="comment-header">
      <h3>评论区</h3>
      <a-button type="text" @click="$emit('update:show', false)">
        <template #icon><CloseOutlined /></template>
      </a-button>
    </div>
    <a-spin :spinning="loading">
      <a-list item-layout="horizontal" :data-source="commentList" class="comment-list">
        <template #renderItem="{ item }">
          <a-list-item class="comment-item">
            <a-list-item-meta>
              <template #title>
                <a-flex justify="space-between" align="center">
                  <div class="left" @click="router.push(`/user/detail/${item.userVO.id}`)">
                    <div class="userName">{{ item.userVO.userName }}</div>
                    <div class="time">{{ dayjs(item.createTime).format('YYYY-MM-DD HH:mm') }}</div>
                  </div>
                  <div class="right">
                    <a-button type="text" class="thumb-btn" @click="thumbComment(item.id)">
                      <LikeOutlined :style="{ color: isThumb ? '#ff4d4f' : '#999999' }" />
                      <span class="thumb-count" :class="{ 'has-thumb': isThumb }">{{
                        item.thumbCount
                      }}</span>
                    </a-button>
                  </div>
                </a-flex>
              </template>
              <template #avatar>
                <a-avatar
                  class="user-avatar"
                  @click="router.push(`/user/detail/${item.userVO.id}`)"
                  :src="item.userVO.userAvatar"
                />
              </template>
              <template #description>
                <div class="comment-content">{{ item.content }}</div>
              </template>
            </a-list-item-meta>
          </a-list-item>
        </template>
      </a-list>
    </a-spin>
    <div class="pagination-container">
      <a-pagination
        v-model:current="commentParam.current"
        :page-size="commentParam.pageSize"
        @change="getCommentList"
        :total="total"
      />
    </div>

    <div class="comment-input-wrapper">
      <div class="comment-input-container">
        <a-input-search
          @pressEnter="sendComment"
          @search="sendComment"
          :enter-button="h(SendOutlined)"
          allow-clear
          v-model:value="comment"
          placeholder="请输入评论内容"
          show-count
          style="width: 100%"
        />
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import PictureCommentWebSocket from '@/utils/websocketwithcomment.ts'
import { PICTURE_COMMENT_MESSAGE_TYPE_ENUM } from '@/constants/picture.ts'
import { message } from 'ant-design-vue'
import { h, onMounted, onUnmounted, ref, watch } from 'vue'
import { useUserStore } from '@/stores/user.ts'
import { listPictureCommentByPageUsingGet } from '@/api/pictureController.ts'
import dayjs from 'dayjs'
import { CloseOutlined, LikeOutlined, SendOutlined } from '@ant-design/icons-vue'
import { useRouter } from 'vue-router'
import { doThumbUsingPost } from '@/api/pictureCommentController.ts'

const router = useRouter()
const userStore = useUserStore()

interface Props {
  pictureId: string
  show: boolean
}

const commentCount = defineModel<number>('commentCount')
const show = defineModel<boolean>('show')
const props = defineProps<Props>()
const commentList = ref<API.PictureCommentVO[]>([])
const loading = ref(false)

// 监听 show 属性变化
watch(show, (newVal) => {
  if (newVal) {
    // 当显示评论区时，加载评论历史并连接 WebSocket
    getCommentList()
    initWebSocket()
  } else {
    // 当关闭评论区时，断开 WebSocket 连接
    if (webSocket) {
      webSocket.disconnect()
      webSocket = null
    }
  }
})

const commentParam = ref<API.listPictureCommentByPageUsingGETParams>({
  pictureId: props.pictureId,
  current: 1,
  pageSize: 10,
})

// 查询评论
const total = ref<number>(0)
const getCommentList = async () => {
  loading.value = true
  try {
    const res = await listPictureCommentByPageUsingGet({
      ...commentParam.value,
    })
    if (res.data.code === 0 && res.data.data) {
      commentList.value = res.data.data.records || []
      total.value = res.data.data.total || 0
      commentCount.value = res.data.data.total || 0
    }
  } catch (error) {
    console.error('获取评论列表失败:', error)
    message.error('获取评论列表失败')
  } finally {
    loading.value = false
  }
}

const comment = ref<string>('')
let webSocket: PictureCommentWebSocket | null = null

const sendComment = () => {
  if (!comment.value) {
    return
  }
  if (!webSocket) {
    initWebSocket()
  }

  // 创建新的评论对象
  const newComment: API.PictureCommentVO = {
    id: Date.now(), // 临时ID
    content: comment.value,
    createTime: new Date().toISOString(),
    userVO: {
      id: userStore.userInfo.id,
      userName: userStore.userInfo.userName,
      userAvatar: userStore.userInfo.userAvatar,
    },
    thumbCount: 0,
    isThumb: false,
  }

  // 添加到评论列表开头
  commentList.value.unshift(newComment)
  commentCount.value = (commentCount.value || 0) + 1

  // 发送WebSocket消息
  if (webSocket) {
    webSocket.sendMessage({
      type: PICTURE_COMMENT_MESSAGE_TYPE_ENUM.COMMENT_ACTION,
      content: comment.value,
    })
  }

  // 清空输入框
  comment.value = ''

  // 刷新评论列表以获取服务器端数据
  getCommentList()
}

const initWebSocket = () => {
  if (!props.pictureId) {
    return
  }
  if (webSocket) {
    webSocket.disconnect()
  }

  webSocket = new PictureCommentWebSocket(props.pictureId)

  webSocket.connect()

  webSocket.on(PICTURE_COMMENT_MESSAGE_TYPE_ENUM.INFO, (msg) => {
    message.info(msg.message)
  })

  webSocket.on(PICTURE_COMMENT_MESSAGE_TYPE_ENUM.ERROR, (msg) => {
    message.info('连接失败')
    message.info(msg.message)
  })

  webSocket.on(PICTURE_COMMENT_MESSAGE_TYPE_ENUM.COMMENT_ACTION, (msg) => {
    // 检查是否已经添加过这条评论
    const isDuplicate = commentList.value.some(
      (comment) => comment.content === msg.content && comment.userVO?.id === msg.userVO?.id,
    )

    if (!isDuplicate) {
      commentList.value.unshift(msg)
      commentCount.value = (commentCount.value || 0) + 1
    }
  })
}

// 评论点赞
const isThumb = ref<boolean>(false)
const thumbComment = async (commentId: string) => {
  await doThumbUsingPost({
    commentId: commentId,
  })
  await getCommentList()
}

onUnmounted(() => {
  if (webSocket) {
    webSocket.disconnect()
    webSocket = null
  }
})

onMounted(() => {
  getCommentList()
  initWebSocket()
})
</script>

<style lang="scss" scoped>
.picture-comment-page {
  margin-top: 24px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  padding: 16px;
  padding-bottom: 80px; // 为固定定位的输入框留出空间

  .comment-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
    padding-bottom: 16px;
    border-bottom: 1px solid #f0f0f0;

    h3 {
      margin: 0;
      font-size: 18px;
      font-weight: 500;
    }
  }

  .comment-list {
    max-height: calc(100vh - 300px);
    overflow-y: auto;
    margin-bottom: 16px;

    .comment-item {
      padding: 16px 0;
      border-bottom: 1px solid #f0f0f0;

      &:last-child {
        border-bottom: none;
      }

      .ant-list-item-meta {
        align-items: flex-start;
      }

      .user-avatar {
        margin-right: 16px;
        cursor: pointer;
        transition: all 0.3s;

        &:hover {
          transform: scale(1.1);
        }
      }

      .left {
        cursor: pointer;
        transition: all 0.3s;

        .userName {
          font-size: 16px;
          font-weight: 500;
          color: #333;
          margin-bottom: 4px;
        }

        .time {
          font-size: 12px;
          color: #999;
        }

        &:hover {
          opacity: 0.8;
        }
      }

      .right {
        .thumb-btn {
          display: flex;
          align-items: center;
          gap: 4px;
          padding: 4px 8px;
          height: auto;
          border-radius: 16px;
          transition: all 0.3s;

          &:hover {
            background: rgba(0, 0, 0, 0.04);
          }

          .anticon {
            font-size: 18px;
          }

          .thumb-count {
            font-size: 14px;
            color: #999;
            transition: all 0.3s;

            &.has-thumb {
              color: #ff4d4f;
            }
          }
        }
      }

      .comment-content {
        font-size: 15px;
        line-height: 1.6;
        color: #333;
        margin-top: 12px;
        padding: 8px 12px;
        background: #f5f7fa;
        border-radius: 8px;
        word-break: break-all;
      }
    }
  }

  .pagination-container {
    text-align: center;
    margin: 16px 0;
  }
}

.comment-input-wrapper {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: #fff;
  padding: 16px;
  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06);
  z-index: 1000;

  .comment-input-container {
    max-width: 800px;
    margin: 0 auto;
  }
}
</style>
